package com.jming.jike.service.backend.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jming.jike.common.BusinessException;
import com.jming.jike.common.PageResult;
import com.jming.jike.dto.backend.SetMealDTO;
import com.jming.jike.entity.Category;
import com.jming.jike.entity.SetMeal;
import com.jming.jike.entity.SetMealDish;
import com.jming.jike.enums.StatusEnum;
import com.jming.jike.mapper.CategoryMapper;
import com.jming.jike.mapper.SetMealMapper;
import com.jming.jike.service.backend.SetMealDishService;
import com.jming.jike.service.backend.SetMealService;
import com.jming.jike.util.CommonUtils;
import com.jming.jike.util.CopyBeanUtils;
import com.jming.jike.vo.backend.CategoryVO;
import com.jming.jike.vo.backend.SetMealDetailVO;
import com.jming.jike.vo.backend.SetMealDishVO;
import com.jming.jike.vo.backend.SetMealVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

import static com.jming.jike.enums.StatusEnum.START_STATUS;

/**
 * @author jinming.zhang
 * @version 0.0.1
 * @date 2022/04/16
 */
@Slf4j
@Service
public class SetMealServiceImpl implements SetMealService {

    @Resource
    private SetMealMapper setMealMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private SetMealDishService setMealDishService;

    @Resource
    private CommonUtils commonUtils;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insert(SetMealDTO setMealDTO) {

        // 套餐信息
        setMealDTO.setId(null);
        SetMeal setMeal = CopyBeanUtils.copyBean(setMealDTO, new SetMeal());

        log.info("SetMealServiceImpl insert 添加套餐信息 入参 {}", JSON.toJSONString(setMeal));
        // 添加套餐信息
        if (setMealMapper.insert(setMeal) <= 0) {
            throw new BusinessException("添加套餐失败!");
        }

        // 添加口味信息
        List<SetMealDish> setMealDishList = setMealDTO.getSetMealDishDTOList().stream().map(smd -> {
            SetMealDish setMealDish = CopyBeanUtils.copyBean(smd, new SetMealDish());
            setMealDish.setId(null);
            setMealDish.setSetMealId(setMeal.getId());
            return setMealDish;
        }).collect(Collectors.toList());
        log.info("SetMealServiceImpl insert 批量添加菜品信息 入参 {}", JSON.toJSONString(setMealDishList));

        // 批量添加菜品信息
        return setMealDishService.saveBatch(setMealDishList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(SetMealDTO setMealDTO) {
        log.info("SetMealServiceImpl update 修改套餐信息 入参 {}", JSON.toJSONString(setMealDTO));

        // 查询套餐信息 如果不存在则抛出异常
        SetMeal setMeal = setMealMapper.selectById(setMealDTO.getId());
        if (ObjectUtils.isEmpty(setMeal)) {
            throw new BusinessException("修改的套餐不存在!");
        }

        // 修改套餐信息
        if (setMealMapper.updateById(CopyBeanUtils.copyBean(setMealDTO, new SetMeal())) <= 0) {
            throw new BusinessException("修改失败!");
        }

        // 删除原来的菜品信息
        if (!setMealDishService.update(Wrappers.<SetMealDish>lambdaUpdate()
                .eq(SetMealDish::getSetMealId, setMealDTO.getId())
                .set(SetMealDish::getIsDeleted, 1))) {
            throw new BusinessException("菜品更新失败!");
        }

        // 添加菜品信息
        List<SetMealDish> setMealDishList = setMealDTO.getSetMealDishDTOList().stream().map(smd -> {
            SetMealDish setMealDish = CopyBeanUtils.copyBean(smd, new SetMealDish());
            setMealDish.setId(null);
            setMealDish.setSetMealId(setMealDTO.getId());
            return setMealDish;
        }).collect(Collectors.toList());
        log.info("SetMealServiceImpl update 修改菜品信息 入参 {}", JSON.toJSONString(setMealDishList));

        // 批量添加菜品信息
        if (!setMealDishService.saveBatch(setMealDishList)) {
            throw new BusinessException("修改失败!");
        }

        return commonUtils.removeImage(setMeal.getImage(), setMealDTO.getImage());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(Long id) {

        // 查询该套餐信息
        SetMeal setMeal = setMealMapper.selectById(id);

        if (ObjectUtils.isEmpty(setMeal)
                || Integer.valueOf(1).equals(setMeal.getIsDeleted())
                || START_STATUS.getCode().equals(setMeal.getStatus())) {

            throw new BusinessException("请检查套餐是否存在或状态是否为停售!");
        }

        // 删除套餐信息
        if (setMealMapper.updateById(SetMeal.builder().id(id).isDeleted(1).build()) <= 0) {
            throw new BusinessException("删除失败!");
        }

        // 删除菜品信息
        if (!setMealDishService.update(Wrappers.<SetMealDish>lambdaUpdate()
                .eq(SetMealDish::getSetMealId, id)
                .set(SetMealDish::getIsDeleted, 1))) {
            throw new BusinessException("删除失败!");
        }
        return commonUtils.removeImage(setMeal.getImage(), null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatus(Long id, Integer status) {

        // 检查入参
        StatusEnum.checkStatus(status);
        // 修改菜品状态
        return setMealMapper.updateById(SetMeal.builder().id(id).status(status).build()) > 0;
    }

    @Override
    public PageResult<SetMealVO> pageQuery(SetMealDTO setMealDTO) {

        // 分页查询套餐信息
        Page<SetMeal> setMealPage = setMealMapper.selectPage(new Page<>(setMealDTO.getPageIndex(), setMealDTO.getPageSize()),
                Wrappers.<SetMeal>lambdaQuery().eq(SetMeal::getIsDeleted, 0)
                        .like(StringUtils.hasText(setMealDTO.getName()), SetMeal::getName, setMealDTO.getName())
                        .orderByDesc(SetMeal::getId));

        if (ObjectUtils.isEmpty(setMealPage) || CollectionUtils.isEmpty(setMealPage.getRecords())) {
            throw new BusinessException("套餐列表为空!");
        }

        // 处理返回数据
        List<SetMealVO> dishVOList = setMealPage.getRecords().stream().map(sm -> {
            SetMealVO setMealVO = CopyBeanUtils.copyBean(sm, new SetMealVO());

            // 查询套餐分类信息 设置套餐分类名称
            Category category = categoryMapper.selectById(sm.getCategoryId());
            setMealVO.setCategoryName(category.getName());
            return setMealVO;
        }).collect(Collectors.toList());

        // 返回分页信息
        return new PageResult<>((int) setMealPage.getCurrent(), (int) setMealPage.getSize(),
                (int) setMealPage.getTotal(), dishVOList);
    }

    @Override
    public SetMealDetailVO queryDetail(Long id) {
        // 查询套餐信息
        SetMealVO setMealVO = CopyBeanUtils.copyBean(setMealMapper.selectById(id), new SetMealVO());

        // 查询分类信息
        CategoryVO categoryVO = CopyBeanUtils.copyBean(categoryMapper.selectById(setMealVO.getCategoryId()), new CategoryVO());

        // 查询菜品列表
        List<SetMealDishVO> setMealDishVOList = CopyBeanUtils.copyBeanList(setMealDishService.list(Wrappers.<SetMealDish>lambdaQuery()
                .eq(SetMealDish::getIsDeleted, 0)
                .eq(SetMealDish::getSetMealId, id)
                .orderByAsc(SetMealDish::getId)), SetMealDishVO.class);

        // 返回详菜品细信息
        return SetMealDetailVO.builder().setMealVO(setMealVO).categoryVO(categoryVO).setMealDishVOList(setMealDishVOList).build();
    }

}
